/*
HTTP简易服务器

自实现HTTP服务器，通过浏览器向服务器发送请求，服务器组织响应，显示Hello World页面以及请求信息；
*/

#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include <string>
#include <algorithm>
#include <iostream>

class Socket
{
static int backlog;

public:
  bool Sock()
  {
    _listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if(_listenfd < 0) {
      return false;
    }
    return true;
  }

  bool Bind(uint16_t port)
  {
    struct sockaddr_in local;
    bzero(&local, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    local.sin_addr.s_addr = inet_addr("0.0.0.0");
    socklen_t len = sizeof(local);
    if(bind(_listenfd, (struct sockaddr*)&local, len) == 0) {
      return true;
    }
    else {
      return false;
    }
  }

  bool Listen()
  {
    return listen(_listenfd, backlog) == 0 ? true : false;
  }

  int Accept()
  {
    struct sockaddr_in client;
    bzero(&client, sizeof(client));
    socklen_t len = 0;
    return accept(_listenfd, (struct sockaddr*)&client, &len);
  }

  bool Connect(std::string ip, uint16_t port)
  {
    struct sockaddr_in server;
    bzero(&server, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(ip.c_str());
    server.sin_port = htons(port);
    if(connect(_listenfd, (struct sockaddr*)&server, sizeof(server) == 0)) {
        return true;
    }
    return false;
  }

private:
  int _listenfd;
};

int Socket::backlog = 10;

class Server
{
public:
  void Init()
  {
    _sock.Sock();
    _sock.Bind(8889);
    _sock.Listen();
  }

  void Get(std::string responseMsg)
  {
    char inbuff[10240]; 
    std::string res;
    while(true)
    {
      int fd =_sock.Accept();
      std::cerr << "get a connect, fd: " << fd << std::endl;
      inbuff[0] = 0;
      ssize_t n = recv(fd, inbuff, sizeof(inbuff), 0);
      if(n == 0) { std::cerr << "connect closed..." << std::endl; }
      inbuff[n] = 0;
      std::string req(inbuff);
      std::cerr << "req: \n" << req << std::endl;
      std::string msg = responseMsg;
      msg += "\n";
      msg += req;
      std::cerr << "total res msg: \n" << msg << std::endl;
    
      res.clear();
      std::string msgLen = std::to_string(msg.size());
      res += "HTTP/1.1 200 OK\r\n";
      res += "Content-Length: "; res += msgLen; res += "\r\n";
      res += "Content-Type: text/plain;charset=UTF-8\r\n";
      res += "\r\n";
      res += msg; 
      std::cerr << "response: \n" << res << std::endl;

      send(fd, res.c_str(), res.size(), 0);
    }
  }

private:
  Socket _sock;
};


int main()
{
  Server svr;
  svr.Init();
  std::cerr << "listening..." << std::endl;
  std::cerr << "ready to get con..." << std::endl;
  svr.Get("Hello World");
  return 0;
}
